home *** CD-ROM | disk | FTP | other *** search
- Path: keats.ugrad.cs.ubc.ca!not-for-mail
- From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
- Newsgroups: comp.lang.c
- Subject: Re: Type casting
- Date: 22 Feb 1996 13:09:52 -0800
- Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
- Message-ID: <4gim30INNo4b@keats.ugrad.cs.ubc.ca>
- References: <4gfnmi$gsc@calvin.risq.qc.ca>
- NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
-
- In article <4gfnmi$gsc@calvin.risq.qc.ca>,
- Pierre Coulombe <pcoulomb@criq.qc.ca> wrote:
- >I have a problem with type casting in Visual C 1.5.
- >I expected the following program to print the value 254 for valI.
- >Instead it gives the output shown below.
- >Can someone tell me where is my mistake ?
- >
- >
- >******** Program *********
- >
- >#include <stdio.h>
- >#include <string.h>
- >#include <stdlib.h>
- >
- >typedef unsigned int UINT;
- >
- >#define MM_TO_UNITS 10.0F
- >
- >void main(void)
- >{
- > float valF;
- > UINT valI;
- > char string[80];
- >
- > strcpy(string, "25.4");
-
- Try char *string = "25.4". This is a waste.
-
- > valI = (UINT) ((float) atof(string) * MM_TO_UNITS);
- > printf("valI = %u\n", valI);
- >
- > sprintf(string, "%f", (float) atof(string) * MM_TO_UNITS);
- > printf("string = %s\n", string);
- >
- > strcpy(string, "25.4");
- > sprintf(string, "%u", (UINT) ((float) atof(string) * MM_TO_UNITS));
- > printf("string = %s\n", string);
- >}
- >
- >
- >******** Output *********
- >
- >valI = 253
- >string = 254.000000
- >string = 253
-
- Floating point numbers are stored in binary. Fractional numbers cannot be
- exactly represented unless they are powers of two. 25.4 is not a fractional
- power of two.
-
- Here is 25.5 in binary:
-
- 11001.1
-
- When you convert that to the popular IEEE double-precision format, you get:
-
- 1.10011 * 10 E 100
-
- The sign is positive, hence the MSB is zero. The exponent of 4 gets added to an
- 11-bit bias, valued 1023:
-
- 01111111111
- + 00000000100
- = 10000000011
-
- So we have:
-
- 0 10000000011 1001100000000000000000000000000000000000000000000000
-
- Which is the 64-bit binary IEEE representation of 25.5. (This is not the only
- representation used on the various platforms that support C. It is not dictated
- by the language standard; I'm only using this to illustrate a point).
-
-
- Now, if you try finding the represenation for 25.4, you will get a repeating
- fraction, because 4/10 = 2/5 cannot be expressed in binary in a finite string of
- digits. Try doing the division
-
- 0.011101
- _______
- 101 | 10.01
- 1 01
- -----
- 1 000
- 101
- -----
- 0110
- 101
- ----
- 00101
-
- and we are back at 101. Hence 0.4(decimal) = 0.0111011101110111... (binary)
-
- Due to the limited precision of the computer representation, the string for
- 25.4 has to get chopped off somwhere. The result is a number that is _less_
- than 25.4. When you multiply it by 10.0, you naturally get a number that is
- less than 254. It could be very close to 254, but no cigar. Hence when you cast
- it to an integer, it gets rounded down to 253.
-
-
- Try this:
-
- integer = (int) (floating + 0.5)
-
- That way you round up or down to the nearest integer. A number slightly less
- than 254 will turn into a number slightly less than 254.5, and hence round to
- 254.
-
-
-
-
-
-
-
- >
- >
- >
-
-
- --
-
-